#include "stdint.h"
#include "stdio.h"
#include "DevicesDelay.h"
#include "DevicesSPI.h"


spi_device_handle_t g_spi0_handle;
spi_device_handle_t g_spi1_handle;
spi_device_handle_t g_spi2_handle;


void vSPI2DMAInit(void)
{
}

void vSPI2Init(void)
{
    spi_bus_config_t buscfg = {0};
    spi_device_interface_config_t devcfg = {0};

    buscfg.mosi_io_num = GPIO_NUM_4;
    buscfg.miso_io_num = GPIO_NUM_5;
    buscfg.sclk_io_num = GPIO_NUM_6;
    buscfg.quadwp_io_num = -1;
    buscfg.quadhd_io_num = -1;
    buscfg.max_transfer_sz = 128;

    devcfg.clock_source = SOC_MOD_CLK_APB;
    devcfg.clock_speed_hz = 1000 * 1000 * 16;
    devcfg.spics_io_num = GPIO_NUM_7;
    devcfg.mode = 0;
    devcfg.queue_size = 7;
    devcfg.pre_cb = NULL;

    //Initialize the SPI bus
    spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);

    //Attach the LCD to the SPI bus
    spi_bus_add_device(SPI2_HOST, &devcfg, &g_spi2_handle);
}

uint8_t ucSPIWriteReadByte(spi_device_handle_t handle, uint8_t ucByte)
{
    spi_transaction_t trans_desc = {0};

    trans_desc.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
    trans_desc.length = 8;
    trans_desc.tx_data[0] = ucByte;
    if(spi_device_polling_transmit(handle, &trans_desc) != ESP_OK)
        return 0;

    return trans_desc.rx_data[0];
}

int8_t cSPIWriteDatas(spi_device_handle_t handle, void *pvBuff, int32_t iLength)
{
    spi_transaction_t trans_desc = {0};

    trans_desc.flags = SPI_TRANS_USE_TXDATA;
    trans_desc.length = 8 * iLength;
    trans_desc.tx_buffer = pvBuff;
    if(spi_device_polling_transmit(handle, &trans_desc) != ESP_OK)
        return 1;

    return 0;
}

int8_t cSPIReadDatas(spi_device_handle_t handle, void *pvBuff, int32_t iLength)
{
    spi_transaction_t trans_desc = {0};

    trans_desc.flags = SPI_TRANS_USE_RXDATA;
    trans_desc.length = 8 * iLength;
    trans_desc.rx_buffer = pvBuff;
    if(spi_device_polling_transmit(handle, &trans_desc) != ESP_OK)
        return 1;

    return 0;
}


/**
 * @brief  设置DMA的数据传输长度，并启动DMA传输
 * @param  DMAy_Channelx：   相应DMA的通道
           Length：          传输长度
 * @retval 无
 */
// void vSPIxDmaAddrAndLenthSet(uint32_t dma_periph, dma_channel_enum channelx, uint32_t uiSourceAddress, uint32_t uiTargetAddress, uint32_t uiLength)
// {
//     // uint32_t uiTime;

//     // /* Disable the peripheral */
//     // dma_channel_disable(dma_periph, channelx);
//     // for(uiTime = 0; (((DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_CHEN) != 0) && (uiTime < 10000)); ++uiTime);

//     // /* 必须要清除所有中断状态，才允许使能DMA */
//     // dma_flag_clear(dma_periph, channelx, DMA_FLAG_G | DMA_FLAG_FTF | DMA_FLAG_HTF | DMA_FLAG_ERR);

//     // /* configure memory base address */
//     // dma_memory_address_config(dma_periph, channelx, uiSourceAddress);

//     // /* configure peripheral base address */
//     // dma_periph_address_config(dma_periph, channelx, uiTargetAddress);

//     // /* Configure DMA Stream data length */
//     // dma_transfer_number_config(dma_periph, channelx, uiLength);

//     // /* Enable the Peripheral */
//     // dma_channel_enable(dma_periph, channelx);
//     // for(uiTime = 0; (((DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_CHEN) == 0) && (uiTime < 10000)); ++uiTime);
// }

int8_t cSPIDmaWriteDatas(spi_device_handle_t handle, void *pvDatas, int32_t iLength, int32_t iWaitUs)
{
    // dma_channel_enum enumChannelx;
    // uint32_t dma_periph;
    // int32_t iTime;

    // if(iLength < 1)
    //     return 1;

    // switch(uiSpiPeriph)
    // {
    //     case SPI0: dma_periph = DMA0; enumChannelx = DMA_CH2; break;
    //     case SPI1: dma_periph = DMA0; enumChannelx = DMA_CH4; break;
    //     case SPI2: dma_periph = DMA1; enumChannelx = DMA_CH1; break;

    //     default : printf("cSPIDmaWriteDatas channel error.\r\n"); return 2;
    // }

    // /* 等待上次DMA传输完成 */
    // while((dma_flag_get(dma_periph, enumChannelx, DMA_FLAG_FTF) == RESET) &&
    //      ((DMA_CHCTL(dma_periph, enumChannelx) & DMA_CHXCTL_CHEN) != 0)   &&
    //       (DMA_CHCNT(dma_periph, enumChannelx) != 0));

    // /* 设置传输地址与长度，并启动DMA发送 */
    // vSPIxDmaAddrAndLenthSet(dma_periph, enumChannelx, (uint32_t)pvDatas, (uint32_t)(&SPI_DATA(uiSpiPeriph)), iLength);

    // spi_dma_enable(uiSpiPeriph, SPI_DMA_TRANSMIT);

    // /* 等待本次DMA传输完成 */
    // if(iWaitUs > 0)
    // {
    //     while(((iWaitUs--) > 0)                                               &&
    //          ((DMA_CHCTL(dma_periph, enumChannelx) & DMA_CHXCTL_CHEN) != 0)   &&
    //           (dma_flag_get(dma_periph, enumChannelx, DMA_FLAG_FTF) == RESET) &&
    //           (DMA_CHCNT(dma_periph, enumChannelx) != 0))
    //     {
    //         vDelayUs(1);
    //     }

    //     /* 等待最后2个字节发送完成 */
    //     for(iTime = 0; (RESET != (SPI_STAT(uiSpiPeriph) & SPI_FLAG_TRANS)) && (iTime < 20000); ++iTime);
    // }

    return 0;
}
